﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace ChessOnline
{
    public class GameLogic
    {
        List<ChessOnlineService.GameCell> boardCells = new List<ChessOnlineService.GameCell>();
        string enemyName = "";
        ChessOnlineService.GameInfo currentGame = new ChessOnlineService.GameInfo();
        List<ChessOnlineService.Coordinate> markedPasses = new List<ChessOnlineService.Coordinate>();
        static ChessOnlineService.Coordinate requestCoordinate = new ChessOnlineService.Coordinate();
        static ChessOnlineService.Coordinate highlightedCoordinate = new ChessOnlineService.Coordinate();

        public GameLogic()
        {
            currentGame.Game_hash = "";
            currentGame.Creator_name = "";
            currentGame.Connected_name = "";
            currentGame.IsStarted = "false";
            currentGame.WinnerName = "";
            currentGame.ActivePlayerHash = "";
        }

        public delegate void EventHandler(object sender, object args);

        public event EventHandler ThrowUpdatePositionsEnded = delegate { };
        /// <summary>
        /// Запросить обновление игровой информации.
        /// </summary>
        /// <param name="user_hash"></param>
        /// <param name="game_hash"></param>
        public void RequestUpdatePositions()
        {
            ChessOnlineService.ChessOnlineServiceClient cl = new ChessOnlineService.ChessOnlineServiceClient();
            cl.UpdatePositionsCompleted += new EventHandler<ChessOnlineService.UpdatePositionsCompletedEventArgs>(UpdatePositionsCompleted);
            cl.UpdatePositionsAsync(Authorization.Instance.GetUserHash(), currentGame.Game_hash);
        }

        /// <summary>
        /// Запрос игровой информации завершен. Можно обрабатывать результаты запроса.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void UpdatePositionsCompleted(object sender, ChessOnlineService.UpdatePositionsCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                boardCells = e.Result;
                ThrowUpdatePositionsEnded(sender, null);
            }
        }

        /// <summary>
        /// Получить все клетки доски в виде списка после запроса.
        /// </summary>
        /// <returns></returns>
        public List<ChessOnlineService.GameCell> GetCells()
        {
            return boardCells;
        }

        /// <summary>
        /// Запросить имя противника.
        /// </summary>
        /// <param name="user_hash"></param>
        /// <param name="game_hash"></param>
        public void RequestEnemyName()
        {
            ChessOnlineService.ChessOnlineServiceClient cl = new ChessOnlineService.ChessOnlineServiceClient();
            cl.GetEnemyNameCompleted += new EventHandler<ChessOnlineService.GetEnemyNameCompletedEventArgs>(GetEnemyNameCompleted);
            cl.GetEnemyNameAsync(Authorization.Instance.GetUserHash(), currentGame.Game_hash);
        }

        /// <summary>
        /// Срабатывает, когда окончено получение имени противника.
        /// </summary>
        public event EventHandler ThrowGetEnemyNameCompleted = delegate { };

        /// <summary>
        /// Запрос имени противника завершился. Можно обрабатывать результаты.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GetEnemyNameCompleted(object sender, ChessOnlineService.GetEnemyNameCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                enemyName = e.Result;
                ThrowGetEnemyNameCompleted(sender, null);
            }
        }

        /// <summary>
        /// Получить имя противника после запроса.
        /// </summary>
        /// <returns>Имя противника.</returns>
        public string GetEnemyName()
        {
            return enemyName;
        }

        /// <summary>
        /// Установить данные игры.
        /// </summary>
        /// <param name="gi">Данные игры.</param>
        public void SetGameInfo(ChessOnlineService.GameInfo gi)
        {
            currentGame = gi;
        }

        /// <summary>
        /// Получить уникальный идентификатор игры.
        /// </summary>
        /// <returns>Уникальный идентификатор игры.</returns>
        public string GetGameHash()
        {
            return currentGame.Game_hash;
        }

        public event EventHandler ThrowUpdateGameInfoCompleted = delegate { };
        public void RequestUpdateGameInfo()
        {
            ChessOnlineService.ChessOnlineServiceClient cl = new ChessOnlineService.ChessOnlineServiceClient();
            cl.UpdateGameInfoCompleted += new EventHandler<ChessOnlineService.UpdateGameInfoCompletedEventArgs>(UpdateGameInfoCompleted);
            cl.UpdateGameInfoAsync(Authorization.Instance.GetUserHash(), currentGame.Game_hash);
        }

        void UpdateGameInfoCompleted(object sender, ChessOnlineService.UpdateGameInfoCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                currentGame = e.Result;
                ThrowUpdateGameInfoCompleted(null, null);
            }
        }

        public string GetWinnerName()
        {
            return currentGame.WinnerName;
        }

        public event EventHandler ThrowPickChessCompleted = delegate { };
        public void RequestPickChess(Point mouse_coord)
        {
            if (currentGame.ActivePlayerHash == Authorization.Instance.GetUserHash())
            {// Если текущий ход наш
                requestCoordinate = GameDrawer.GetBoardCoordByMouse(mouse_coord);
                ChessOnlineService.ChessOnlineServiceClient cl = new ChessOnlineService.ChessOnlineServiceClient();
                cl.PickChessCompleted += new EventHandler<ChessOnlineService.PickChessCompletedEventArgs>(PickChessCompleted);
                cl.PickChessAsync(Authorization.Instance.GetUserHash(), currentGame.Game_hash, requestCoordinate);
            }            
        }

        void PickChessCompleted(object sender, ChessOnlineService.PickChessCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                markedPasses = e.Result;
                if (e.Result.Count > 0)
                {
                    highlightedCoordinate = requestCoordinate;
                }
                ThrowPickChessCompleted(null, null);
            }
        }

        public List<ChessOnlineService.Coordinate> GetMarkedPasses()
        {
            return markedPasses;
        }

        public static ChessOnlineService.Coordinate GetHighlightedCoord()
        {
            return highlightedCoordinate;
        }

        public event EventHandler ThrowMoveChessCompleted = delegate { };

        public void RequestMoveChess(Point mouse_coord)
        {
            ChessOnlineService.Coordinate new_coord = GameDrawer.GetBoardCoordByMouse(mouse_coord);
            ChessOnlineService.ChessOnlineServiceClient cl = new ChessOnlineService.ChessOnlineServiceClient();
            cl.MoveChessCompleted += new EventHandler<ChessOnlineService.MoveChessCompletedEventArgs>(MoveChessCompleted);
            cl.MoveChessAsync(Authorization.Instance.GetUserHash(), currentGame.Game_hash, highlightedCoordinate, new_coord);
        }

        void MoveChessCompleted(object sender, ChessOnlineService.MoveChessCompletedEventArgs e)
        {
            if (e.Error == null && e.Result == "true")
            {
                requestCoordinate = new ChessOnlineService.Coordinate();
                highlightedCoordinate = new ChessOnlineService.Coordinate();
                ThrowMoveChessCompleted(null, null);
            }
        }

        public bool IsStarted()
        {
            return currentGame.IsStarted == "true" ? true : false;
        }

        public void RequestQuitGame()
        {
            // TODO: implement this!
            ChessOnlineService.ChessOnlineServiceClient cl = new ChessOnlineService.ChessOnlineServiceClient();
            cl.QuitGameCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(QuitGameCompleted);
            cl.QuitGameAsync(Authorization.Instance.GetUserHash(), currentGame.Game_hash);
        }

        void QuitGameCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {// TODO: эта функция не обязательна!
            throw new NotImplementedException();
        }
    }
}
